package baseObjectContract;
import assertTools.DecoratorTools;
import baseObject.BaseObjectsFactory;
import baseObject.IBrick;
import baseObject.IBrickBreaker;
import baseObject.IRectObj;
import baseObjectDecorator.BrickDecorator;

public class BrickContract extends BrickDecorator{
	private IBrick brick;
	private IBrick brickPrime;
	
	public BrickContract(IBrick brick){
		super(brick);
		this.brick = brick;
	}
	
	public void init(int x, int y, int width, int height){
		DecoratorTools.checkPre(x >= 0 && y >= 0 && width >= 0 && height >= 0);
		DecoratorTools.checkPre(x + width <= IBrickBreaker.XMAX && y + height <= IBrickBreaker.YMAX);
		
		brick = BaseObjectsFactory.newBrick(x, y, width, height);
	
		DecoratorTools.checkPost(super.getResistance() == 3);
		DecoratorTools.checkPost(super.isBreakable());
		
		this.checkInvariantBrick();
	}
	
	private void checkInvariantBrick(){
		brickPrime = (IBrick) super.cloneObj();
		DecoratorTools.checkInv(super.getResistance() >= 0);
		DecoratorTools.checkInv(super.isAffectedBy(brickPrime));
	}

	public boolean isBreakable() {
		return super.isBreakable();
	}

	public int getResistance() {
		return super.getResistance();
	}


	public void setBreakeable(boolean breakeable) {
		IBrick birckAtOld = this.brick;
		
		this.checkInvariantBrick();
		
		super.setBreakeable(breakeable);
		DecoratorTools.checkPost(super.isBreakable() == breakeable);
		DecoratorTools.checkPost(super.getResistance() == birckAtOld.getResistance());
		
		this.checkInvariantBrick();
	}

	public void setResistance(int r) {
		this.checkInvariantBrick();
		
		super.setResistance(r);
		
		DecoratorTools.checkPost(super.getResistance() == r);
		
		this.checkInvariantBrick();
	}


	public void hit() {
		IBrick birckAtOld = (IBrick) this.brick.cloneObj();
		this.checkInvariantBrick();
		DecoratorTools.checkPre(super.isBreakable() && super.getResistance() >= 1);
		
		super.hit();
		
		DecoratorTools.checkPost(super.getResistance() == birckAtOld.getResistance() - 1);
		this.checkInvariantBrick();
	}

	@Override
	public Object cloneObj() {
		return super.cloneObj();
	}

	@Override
	public boolean isOnTop(IRectObj iRectObj) {
		return this.brick.isOnTop(iRectObj);
	}
}
